home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 001 / pibt40s1.arc / CMPSTR.MOD < prev    next >
Encoding:
Text File  |  1987-03-15  |  5.9 KB  |  105 lines

  1. (*
  2.    For MS/PC-DOS versions of Turbo only. Known to work correctly with version
  3.    3.01A of Turbo Pascal, should work with earlier versions.
  4.  
  5.    The inline string comparison functions included here provide high-speed
  6.    replacements for those in the Turbo run-time library.  If you have been
  7.    using the earlier version of CMPSTR.INC, please note the following:
  8.      (1) A second routine has been added which accepts literals, constants,
  9.          and function results as parameters, as well as string variables.
  10.      (2) To avoid confusion, I have kept the name of the old routine the
  11.          same, and given the new one the name CompareStr.
  12.      (3) The new version of CompStr is slightly faster than the old.
  13.  
  14.    Both routines offer two advantages over the standard library routines.
  15.    (1) In standard Turbo, the statement "TrueFalse := (String1 = String2)"
  16.    will tell you if the strings are equal, but if they aren't you have to
  17.    execute a second statement to find out why.  These return Less, Equal,
  18.    or Greater in one swoop.  (2) Speed.  I have tested CompStr against an
  19.    essentially equivalent function using the standard library routines:
  20.    the tests indicated that CompStr will always be at least 2.5 times
  21.    faster; on average about 3.5 to 4 times faster.  (In the worst case--
  22.    2 255-character strings, 1st one different--CompStr tested 27+ times
  23.    faster.)  Tests of CompareStr showed that it is 1.4 to 2.9 times faster
  24.    than an equivalent function coded in Turbo, probably about twice as fast
  25.    on average.
  26.         One last note.  As given here, these functions return a result of a
  27.    scalar type: Comparer = ( Less, Equal, Greater).  If you wish, you can
  28.    change this to 'Byte' and interpret the results as follows:
  29.           0 : String1 < String2;  - Less -
  30.           1 : String1 = String2;  - Equal -
  31.           2 : String1 > String2;  - Greater -
  32.    To test for "<=", check for "not Greater" or "< 2"; to test for ">=",
  33.    check for "not Less" or "> 0".
  34.  
  35.    Special thanks to David B. Rein for suggestions on optimizing the code.
  36.  
  37.    Written by Brian Foley CompuServe ID # [76317,3247]
  38.    Last update: 5/12/86
  39.  
  40.    Updated for use in PibTerm v4.0 by Phil Burns.
  41.    Principal change:  Handle null strings correctly.
  42.  
  43.  How CompStr and CompareStr use registers:
  44.  AL initially indicates which string is longer and is coded the same way as
  45.  the function result: 0 => S1 is shorter; 1 => S1 is the same length as S2;
  46.  2 => S1 is longer.  The strings will be compared up to the end of the
  47.  shorter string, whose length is put into CX.  If the strings evaluate as
  48.  equal up to that point, then by definition the longer string is greater,
  49.  and BL will already contain the function result.  Here's a quick example:
  50.        Result := CompareStr( 'BILL', 'BILLY' );
  51.  Here, CX will be set initially to 4 = Length(S1), and AL will be set to 0,
  52.  to indicate that S1 is shorter.  The comparison will go to 4 characters,
  53.  and the strings will evaluate as equal up to that point.  Since AL already
  54.  equals 0, it gives us the correct result: 0 => S1 < S2.  In cases where the
  55.  strings do not evaluate as equal, the length record will be wiped out, and
  56.  AL will be set to 0 or 2, depending upon the outcome of the comparison.
  57.  
  58. *)
  59.  
  60. FUNCTION CompareStr( S1, S2 : AnyStr ) : Comparer;
  61.  
  62. { IMPORTANT NOTE: S1 and S2 *must* be of type String[ 255 ] }
  63.  
  64. BEGIN
  65.  
  66. INLINE(
  67.   $1E                    {          PUSH    DS                   ;Save data segment register}
  68.                          {;}
  69.   /$30/$ED               {          XOR     CH,CH                ;Clear register holding S1's length}
  70.   /$88/$E8               {          MOV     AL,CH                ;S1 < S2 is initial default.}
  71.                          {;}
  72.   /$8C/$D2               {          MOV     DX,SS                ;Move SS into ES}
  73.   /$8E/$C2               {          MOV     ES,DX                ;}
  74.   /$8E/$DA               {          MOV     DS,DX                ;and DS}
  75.   /$8D/$BE/>S2           {          LEA     DI,[BP+>S2]          ;ES:DI points to S2}
  76.   /$8A/$1D               {          MOV     BL,[DI]              ;BL is length of S2}
  77.   /$47                   {          INC     DI}
  78.   /$8D/$B6/>S1           {          LEA     SI,[BP+>S1]          ;DS:SI points to S1}
  79.   /$8A/$0C               {          MOV     CL,[SI]              ;CL is length of S1}
  80.   /$46                   {          INC     SI}
  81.   /$38/$D9               {          CMP     CL,BL                ;See if lengths are equal}
  82.   /$74/$06               {          JE      EqualLen             ;Yes}
  83.                          {;}
  84.   /$72/$0A               {          JB      Compare              ;If Length( S2 ) < Length( S1 ),}
  85.   /$FE/$C0               {          INC     AL                   ;assume equal for the present.}
  86.   /$88/$D9               {          MOV     CL,BL                ;Only compare up to min of lengths.}
  87.                          {;}
  88.   /$FE/$C0               {EqualLen: INC     AL                   ;Set to return strings equal.}
  89.   /$38/$E9               {          CMP     CL,CH                ;See if lengths zero -- immediate}
  90.   /$74/$0B               {          JE      Return               ;return (with strings equal) if so.}
  91.                          {;}
  92.   /$FC                   {Compare:  CLD                          ;Forward direction for compare}
  93.   /$F3/$A6               {          REPE    CMPSB                ;Perform comparison}
  94.   /$74/$06               {          JE      Return               ;Return if strings equal.}
  95.   /$B0/$02               {          MOV     AL,2                 ;Mark S1 > S2.}
  96.   /$77/$02               {          JA      Return               ;}
  97.   /$30/$C0               {          XOR     AL,AL                ;Mark S1 < S2.}
  98.                          {;}
  99.   /$88/$86/$04/$02       {Return:   MOV     [BP+$204],AL         ;Store function return value.}
  100.                          {;}
  101.   /$1F                   {          POP     DS}
  102. );
  103.  
  104. END;
  105.